package tokenutil

import (
	"gitee.com/zhongguo168a/gocodes/datax/mapx"
	"github.com/dgrijalva/jwt-go"
	"github.com/pkg/errors"
	"time"
)

var (
	ErrParseFail   = errors.New("token parse fail")
	ErrIllegal     = errors.New("token invalid")
	ErrExpired     = errors.New("token expired")
	ErrUseNotmatch = errors.New("token use notmatch")
)

// CreateLater 令牌-创建
func CreateToken(info *TokenInfo, hmacSampleSecret string) (t string, err error) {
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
		"uid":  info.Uid,
		"role": info.Role,
		"time": int(time.Now().Unix()),
	})

	t, err = token.SignedString([]byte(hmacSampleSecret))
	if err != nil {
		err = errors.Wrap(err, "signed string")
		return
	}

	return
}

func ParseToken(tok, secret string) (info *TokenInfo, err error) {
	t, err := jwt.Parse(tok, func(*jwt.Token) (interface{}, error) {
		return []byte(secret), nil
	})
	if err != nil {
		return nil, ErrParseFail
	}
	info = &TokenInfo{}
	info.JwtToken = t
	var tokenMap = t.Claims.(jwt.MapClaims)

	info.Uid = mapx.String(tokenMap, "uid")
	info.Role = mapx.String(tokenMap, "role")
	info.Time = int32(mapx.Int(tokenMap, "time"))
	return
}

// TokenInfo 令牌信息
type TokenInfo struct {
	// 用户id
	Uid string
	// 权限
	Role string
	//
	Time int32
	//
	JwtToken *jwt.Token
}

func (info *TokenInfo) GetLogObj() (r map[string]interface{}) {
	r = map[string]interface{}{}
	if info == nil {
		return
	}
	r["uid"] = info.Uid
	r["role"] = info.Role
	r["time"] = info.Time
	return
}

// Valid 验证token
func (info *TokenInfo) Valid(expiredTime int) (err error) {
	if info.JwtToken.Valid == false {
		err = ErrIllegal
		return
	}

	if time.Now().Unix() > time.Unix(int64(info.Time), 0).Add(time.Duration(int(time.Second)*expiredTime)).Unix() {
		err = ErrExpired
		return
	}

	return
}
